package com.example.campus_order_sb.service.impl;

import com.example.campus_order_sb.dto.OrderItemResponse;
import com.example.campus_order_sb.dto.OrderResponse;
import com.example.campus_order_sb.dto.PlaceOrderRequest;
import com.example.campus_order_sb.entity.Food;
import com.example.campus_order_sb.entity.Order;
import com.example.campus_order_sb.entity.OrderItem;
import com.example.campus_order_sb.entity.User;
import com.example.campus_order_sb.enums.OrderStatus;
import com.example.campus_order_sb.repository.FoodRepository;
import com.example.campus_order_sb.repository.OrderItemRepository;
import com.example.campus_order_sb.repository.OrderRepository;
import com.example.campus_order_sb.repository.UserRepository;
import com.example.campus_order_sb.service.OrderService;
import jakarta.persistence.EntityNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    private OrderItemRepository orderItemRepository;

    @Autowired
    private FoodRepository foodRepository;

    @Autowired
    private UserRepository userRepository;

    @Override
    @Transactional
    public OrderResponse createOrder(Integer userId, PlaceOrderRequest request) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new EntityNotFoundException("用户不存在"));

        Order order = new Order();
        order.setUserId(userId);
        order.setTotalPrice(request.getTotalPrice());
        order.setAddress(request.getAddress());
        order.setAddressDetail(request.getAddressDetail());
        order.setRemark(request.getRemark());
        order.setStatus(OrderStatus.PENDING);

        Order savedOrder = orderRepository.save(order);

        List<OrderItem> orderItems = new ArrayList<>();
        for (com.example.campus_order_sb.dto.OrderItemRequest itemRequest : request.getItems()) {
            Food food = foodRepository.findById(itemRequest.getFoodId())
                    .orElseThrow(() -> new EntityNotFoundException("商品不存在: " + itemRequest.getFoodId()));

            OrderItem orderItem = new OrderItem();
            orderItem.setOrderId(savedOrder.getId());
            orderItem.setFoodId(food.getId());
            orderItem.setQuantity(itemRequest.getQuantity());
            orderItem.setPrice(food.getPrice());
            orderItems.add(orderItem);
        }

        List<OrderItem> savedItems = orderItemRepository.saveAll(orderItems);

        return convertToOrderResponse(savedOrder, savedItems);
    }

    @Override
    public OrderResponse getOrderById(Integer orderId) {
        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new EntityNotFoundException("订单不存在: " + orderId));

        List<OrderItem> items = orderItemRepository.findByOrderId(orderId);

        return convertToOrderResponse(order, items);
    }

    @Override
    public List<OrderResponse> getUserOrders(Integer userId) {
        List<Order> orders = orderRepository.findByUserIdOrderByCreatedAtDesc(userId);

        return orders.stream()
                .map(order -> {
                    List<OrderItem> items = orderItemRepository.findByOrderId(order.getId());
                    return convertToOrderResponse(order, items);
                })
                .collect(Collectors.toList());
    }

    @Override
    public List<OrderResponse> getAllOrders() {
        List<Order> orders = orderRepository.findAllByOrderByCreatedAtDesc();

        return orders.stream()
                .map(order -> {
                    List<OrderItem> items = orderItemRepository.findByOrderId(order.getId());
                    return convertToOrderResponse(order, items);
                })
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public OrderResponse updateOrderStatus(Integer orderId, OrderStatus status) {
        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new EntityNotFoundException("订单不存在: " + orderId));

        order.setStatus(status);
        Order updatedOrder = orderRepository.save(order);

        List<OrderItem> items = orderItemRepository.findByOrderId(orderId);

        return convertToOrderResponse(updatedOrder, items);
    }

    @Override
    @Transactional
    public OrderResponse cancelOrder(Integer orderId) {
        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new EntityNotFoundException("订单不存在: " + orderId));

        if (order.getStatus() == OrderStatus.PENDING || order.getStatus() == OrderStatus.PAID) {
            order.setStatus(OrderStatus.CANCELLED);
            Order updatedOrder = orderRepository.save(order);

            List<OrderItem> items = orderItemRepository.findByOrderId(orderId);

            return convertToOrderResponse(updatedOrder, items);
        } else {
            throw new IllegalStateException("订单状态不允许取消");
        }
    }

    private OrderResponse convertToOrderResponse(Order order, List<OrderItem> items) {
        OrderResponse response = new OrderResponse();
        response.setId(order.getId());
        response.setUserId(order.getUserId());

        User user = userRepository.findById(order.getUserId()).orElse(null);
        if (user != null) {
            response.setUsername(user.getUsername());
        }

        response.setTotalPrice(order.getTotalPrice());
        response.setAddress(order.getAddress());
        response.setAddressDetail(order.getAddressDetail());
        response.setRemark(order.getRemark());
        response.setStatus(order.getStatus());
        response.setCreatedAt(order.getCreatedAt());
        response.setUpdatedAt(order.getUpdatedAt());

        List<OrderItemResponse> itemResponses = items.stream()
                .map(item -> {
                    OrderItemResponse itemResponse = new OrderItemResponse();
                    itemResponse.setId(item.getId());
                    itemResponse.setFoodId(item.getFoodId());

                    Food food = foodRepository.findById(item.getFoodId()).orElse(null);
                    if (food != null) {
                        itemResponse.setFoodName(food.getName());
                        itemResponse.setFoodImage(food.getImage());
                    }

                    itemResponse.setQuantity(item.getQuantity());
                    itemResponse.setPrice(item.getPrice());

                    return itemResponse;
                })
                .collect(Collectors.toList());

        response.setItems(itemResponses);

        return response;
    }
}